
#include "main.h"



#define MC33771_SPICSB(n)		PTD->PDOR = (PTD->PDOR & (~(1 <<3))) | (n << 3);

lpspi_tx_cmd_config_t MC33771_Lpspi_TxCfg = 
{
	.whichPcs = LPSPI_PCS0,										/* PCS=0: Transfer using PCS0 */
	.width = LPSPI_SINGLE_BIT_XFER,						/* WIDTH=0: Single bit transfer */
  .clkPhase = LPSPI_CLOCK_PHASE_2ND_EDGE,		/* CPHA=0: Change data on SCK lead'g, capture on trail'g edge   LPSPI_CLOCK_PHASE_2ND_EDGE*/
  .clkPolarity = LPSPI_SCK_ACTIVE_HIGH,			/* CPOL=0: SCK inactive state is HIGH */
	.lsbFirst = false,												/* LSBF=0: Data is transfered MSB first */
	.txMask 	= false,												/* TXMSK=0: Normal transfer: data loaded from tx FIFO */                          
	.rxMask		= false,												/* RXMSK=0: Normal transfer: rx data stored in rx FIFO */
	.contTransfer = true,											/* CONTC=0: Continuous transfer disabled */
	.contCmd = false ,												/* Master option to change cmd word within cont transfer. */
	.frameSize = 8,														/* FRAMESZ=7: # bits in frame = 7+1=8 */
	.preDiv    = 1,														/* PRESCALE=2: Functional clock divided by 2*2 = 4 */
	.byteSwap = false, 												/* BYSW=0: Byte swap disabled */
};

Bsw_Lpspi_Cfg 	MC33771_LPSPI1_Cfg = 
{
	.base = LPSPI2,													/*SPI硬件模块选择:  LPSPI2*/
	.clockName = LPSPI2_CLK,
	.clockSource = 6,
	.b_TxDmaCmd = true ,											/* TXDMA not used */
	.b_RxDmaCmd = true ,												/* RXDMA not used */
	.Lpspi_mode = LPSPI_MASTER,								/* Set for master mode */ 
	
	.PinCfg = LPSPI_SDI_IN_SDO_OUT, 
	.DataOutCfg = LPSPI_DATA_OUT_RETAINED, 
	.b_Pcs_Enable = true,
	.b_SampleDly = 	false,
	.txWater = 1,
	.rxWater = 0,
	.Cmd_Cfg = &MC33771_Lpspi_TxCfg,
	.u32_SCKDIV = 8,
	.u32_SCKPCS = 20,
	.u32_PCSSCK = 20,
	.u32_DBT = 10,
	.Lpspi_Pcs = LPSPI_PCS0,
  .PcsPolarity = LPSPI_ACTIVE_LOW,
};


BSW_Dma_Cfg SPI1_TxDma =
{
	.DMA_Ch 					=	DMA_CH2,				/*配置DMA通道    				eg: DMA_CH0								*/
	.IRQn						=	DMA2_IRQn,
//	.SrcAddr					=	(u32)TCD0_Source,		/*配置源地址				eg: (u32)Dma_Src			*/
	.SrcOffset					=	1,						/*自动累加源地址大小			eg: 1 每次传输地址自动加1			*/
	.SrcTrfSize 				=	EDMA_TRANSFER_SIZE_1B,	/*源地址单次传输几个字节		eg:	EDMA_TRANSFER_SIZE_1B 	*/
	.SrcLastAdj       			= 	0,						/*配置传输完成时是否更改源地址	eg: 0 不更改源地址				*/
	
//	.DestAddr					=	(u32)TCD0_Dest,			/*配置目标地址				eg: (u32)Dma_Dest			*/
	.DestOffset					=	0,						/*自动累加目标地址大小			eg: 1 每次传输地址自动加1			*/
	.DestTrfSize				=	EDMA_TRANSFER_SIZE_1B,	/*目标地址单次传输几个字节		eg:	EDMA_TRANSFER_SIZE_1B 	*/
	.DestLastAdj      			= 	0,						/*配置传输完成时是否更改目标地址	eg: 0 不更改目标地址				*/
	
	.SetNbytes					=	1,						/*DMA开启每次传输几个字节		eg: 1  每次传输1个字节			*/
	.SetMjrCount				=	5,						/*DMA开启每次循环的次数 		eg: 10 每次传输多少次			*/
	.b_MjrCpltIrq				= 	true,					/*配置是否传输完成中断										*/
	.b_HlfCpltIrq				= 	false,
	.b_DmaRqstDone				=	true,					/*传输结束是否自动关闭DMA		eg: true 自动关闭DMA 			*/
	.b_Dma_En					=	false,					/* DMA使能配置				eg: true 使能DMA触发传输		*/
};

BSW_Dma_Cfg SPI1_RxDma =
{
	.DMA_Ch 			=	DMA_CH3,						/*配置DMA通道    									eg: DMA_CH0								*/
	.IRQn				=	DMA3_IRQn,
//	.SrcAddr			=	(u32)TCD0_Source,				/*配置源地址											eg: (u32)Dma_Src					*/
	.SrcOffset			=	0,								/*自动累加源地址大小							eg: 1 每次传输地址自动加1	*/
	.SrcTrfSize 		=	EDMA_TRANSFER_SIZE_1B,			/*源地址单次传输几个字节					eg:	EDMA_TRANSFER_SIZE_1B */
	.SrcLastAdj       	= 	0,								/*配置传输完成时是否更改源地址		eg: 0 不更改源地址				*/
	
//	.DestAddr			=	(u32)TCD0_Dest,					/*配置目标地址										eg: (u32)Dma_Dest					*/
	.DestOffset			=	1,								/*自动累加目标地址大小						eg: 1 每次传输地址自动加1	*/
	.DestTrfSize		=	EDMA_TRANSFER_SIZE_1B,			/*目标地址单次传输几个字节				eg:	EDMA_TRANSFER_SIZE_1B */
	.DestLastAdj      	= 	0,								/*配置传输完成时是否更改目标地址	eg: 0 不更改目标地址			*/
	
	.SetNbytes			=	1,								/*DMA开启每次传输几个字节					eg: 1  每次传输1个字节		*/
	.SetMjrCount		=	6,								/*DMA开启每次循环的次数 					eg: 10 每次传输多少次			*/
	.b_MjrCpltIrq		= 	true,							/*配置是否传输完成中断		*/
	.b_HlfCpltIrq		= 	false,
	.b_DmaRqstDone		=	true,							/*传输结束是否自动关闭DMA					eg: true 自动关闭DMA 			*/
	.b_Dma_En			=	false,							/* DMA使能配置										eg: true 使能DMA触发传输	*/
};






const MC33771_CMD_FLG  MC33771_Init[16] =
{
		/**************************初始化******************************/
		{	0x00,	0x00,	INIT,	0x01,	0x74	},			/*1	*/
		{	0x00,	0x01,	INIT,	0x02,	0x0B	},			/*2	*/
		{	0x13,	0x86,	SYS_CFG1,	0x12,	0x39	},		/*3	*/
		{	0x03,	0x30,	SYS_CFG2,	0x12,	0x68	},		/*4	*/
		{	0x00,	0x00,	GPIO_CFG1,	0x12,	0xDE	},		/*5	*/
		{	0x00,	0x00,	GPIO_CFG2,	0x12,	0xCA	},		/*6	*/
		{	0x00,	0x00,	FAULT1_STATUS,	0x12,	0xDD	},	/*7	*/
		{	0x00,	0x00,	FAULT2_STATUS,	0x12,	0x34	},	/*8	*/
		{	0x00,	0x00,	FAULT3_STATUS,	0x12,	0x20	},	/*9	*/
		{	0xFF,	0xFF,	FAULT_MASK1,	0x12,	0x4D 	},	/*10	*/
		{	0xFF,	0xFF,	FAULT_MASK2,	0x12,	0x09	},	/*11	*/
		{	0xFF,	0xFF,	FAULT_MASK3,	0x12,	0xE0	},	/*12	*/
		{	0x0C,	0xBF,	ADC_CFG,	0x12,	0x43,	},		/*13	*/
		{	0x00,	0x00,	0x00,	0x00,	0xB2	},			/*14	*/
};

const MC33771_CMD_FLG	Mc33771_Clear[8] =
{
	{	0x00,	0x00,	FAULT1_STATUS,	0x12,	0xDD	},	/*1	*/
	{	0x00,	0x00,	FAULT2_STATUS,	0x12,	0x34	},	/*2	*/
	{	0x00,	0x00,	FAULT3_STATUS,	0x12,	0x20	},	/*3	*/
	{	0xFF,	0xFF,	FAULT_MASK1,	0x12,	0x4D 	},	/*4	*/
	{	0xFF,	0xFF,	FAULT_MASK2,	0x12,	0x09	},	/*5	*/
	{	0xFF,	0xFF,	FAULT_MASK3,	0x12,	0xE0	},	/*6	*/
	{	0x00,	0x01,	SYS_CFG_GLOBAL,	0x12,	0xB1	},	/*7	*/
	{	0x00,	0x00,	0x00,	0x00,	0xB2	},			/*8	*/
};

/************读取MC33771的电芯当前参数启动下次转换*************/
const MC33771_CMD_FLG Mc33771_VCT[40] =
{
		{	0x00,	0x01,	MEAS_CELL1,	0x11,	0xA9	},	/*1	*/
		{	0x00,	0x01,	MEAS_CELL2,	0x11,	0X16	},	/*2	*/
		{	0x00,	0x01,	MEAS_CELL3,	0x11,	0xFF	},	/*3	*/
		{	0x00,	0x01,	MEAS_CELL4,	0x11,	0xEB	},	/*4	*/
		{	0x00,	0x01,	MEAS_CELL6,	0x11,	0xC3	},	/*5	*/
		{	0x00,	0x01,	MEAS_CELL7,	0x11,	0x2A	},	/*6	*/
		{	0x00,	0x01,	MEAS_CELL8,	0x11,	0x3E	},	/*7	*/
		{	0x00,	0x01,	MEAS_CELL9,	0x11,	0xD7	},	/*8	*/
		{	0x00,	0x01,	MEAS_CELL10,	0x11,	0x93	},	/*9	*/
		{	0x00,	0x01,	MEAS_CELL11,	0x11,	0x7A	},	/*10	*/
		{	0x00,	0x01,	MEAS_CELL12,	0x11,	0x6E	},	/*11	*/
		{	0x00,	0x01,	MEAS_CELL13,	0x11,	0x87	},	/*12	*/
		{	0x00,	0x01,	MEAS_CELL14,	0x11,	0x46	},	/*13	*/
		{	0x00,	0x01,	MEAS_AN0,	0x11,	0x68	},	/*14	*/
		{	0x00,	0x01,	MEAS_AN1,	0x11,	0x81	},	/*15	*/
		{	0x00,	0x01,	MEAS_AN2,	0x11,	0x95	},	/*16	*/
		{	0x00,	0x01,	MEAS_AN3,	0x11,	0x7C	},	/*17	*/
		{	0x00,	0x01,	MEAS_AN4,	0x11,	0xBD	},	/*18	*/
		{	0x00,	0x01,	MEAS_AN5,	0x11,	0x54	},	/*19	*/
		{	0x00,	0x01,	MEAS_AN6,	0x11,	0x40	},	/*20	*/
		{	0x00,	0x01,	MEAS_ISENSE1,	0x11,	0X52	},	/*21	*/
		{	0x00,	0x01,	MEAS_ISENSE2,	0x11,	0xBB	},	/*22	*/
		{	0x00,	0x01,	MEAS_STACK,	0x11,	0xAF	},	/*23	*/
		{	0x00,	0x01,	MEAS_IC_TEMP,	0x11,	0x2C	},	/*24	*/
		{	0x00,	0x01,	COULOUMB_CNT1,	0x11,	0xDA	},	/*25	*/
		{	0x00,	0x01,	COULOUMB_CNT2,	0x11,	0x33	},	/*26	*/
		{	0x00,	0x01,	CC_NB_SAMPLES,	0x11,	0xCE	},	/*27	*/

		{	0x00,	0x01,	FAULT1_STATUS,	0x11,	0xA2,	},	/*28	*/
		{	0x00,	0x01,	FAULT2_STATUS,	0x11,	0x4B,	},	/*29	*/
		{	0x00,	0x01,	FAULT3_STATUS,	0x11,	0x5F,	},	/*30	*/

		{	0x00,	0x00,	FAULT1_STATUS,	0x12,	0xDD	},	/*31	*/
		{	0x00,	0x00,	FAULT2_STATUS,	0x12,	0x34	},	/*32	*/
		{	0x00,	0x00,	FAULT3_STATUS,	0x12,	0x20	},	/*33	*/
		{	0x0C,	0xBF,	ADC_CFG,	0x12,	0x43,	},	/*34	*/
		{	0x00,	0x00,	0x00,	0x00,	0xB2	},	/*35	*/
};


const MC33771_CMD_FLG  MC33771_NORMAL[3] =
{
		{	0x13,	0x86,	SYS_CFG1,	0x12,	0x39	},
		{	0x0C,	0xBF,	ADC_CFG,	0x12,	0x43	},	/*启动AD转换*/
		{	0x00,	0x00,	0x00,	0x00,	0xB2	},	/*3	*/
};








typedef struct
{
	u8  u8_XX;      /*无效数据位*/
	u8	u8_DataL;
	u8	u8_DataH;
	u8  u8_Addr;
	u8  u8_CID_Cmd;
	u8  u8CRC;
}MC33771_REVE_FLG;


/************定义接收缓存buff**********/
MC33771_REVE_FLG G_MC3371_Rxbuff[30];
u32 G_MC33771_Rx_Addr;			/*数据接收的首地址*/
u32	G_MC33771_Tx_Addr;			/*数据发送的首地址*/

bool G_b_DMA3_IDE_Flg = false;
u8 G_u8_Arr_len = 0;




u8 G_u8_Crc_Err_Count = 0;
u8 G_u8_Data_Err_Count = 0;

void ECU_MC33771_RE_INIT(void)
{
	/********************LPSPI1配置**************************/
	BSW_LPSPI_INIT(MC33771_LPSPI1_Cfg);
	/*****************DMA通道对应的设置**********************/
	BSW_DMAMUX_INIT(SPI1_TxDma.DMA_Ch,EDMA_REQ_LPSPI2_TX);
	SPI1_TxDma.SrcAddr = G_MC33771_Tx_Addr;
	SPI1_TxDma.DestAddr = (u32)&(LPSPI2->TDR);
	BSW_DMA_INIT_CFG(SPI1_TxDma);

	BSW_DMAMUX_INIT(SPI1_RxDma.DMA_Ch,EDMA_REQ_LPSPI2_RX);
	SPI1_RxDma.SrcAddr = (u32)&(LPSPI2->RDR);
	SPI1_RxDma.DestAddr = G_MC33771_Rx_Addr;
	BSW_DMA_INIT_CFG(SPI1_RxDma);
}

u8 G_u8_BCC_Rest_Count = 0;
u8 ECU_MC33771_REST(void)
{
	u8 u8_Status = 0;
	if(G_u8_BCC_Rest_Count  >= 1)
	{
		BSW_GPIO_SetBits(PTA,13);
		G_u8_BCC_Rest_Count = 0;
		u8_Status = true;
	}
	else
	{
		G_u8_BCC_Rest_Count ++;
		ECU_MC33771_RE_INIT();
		BSW_GPIO_ResetBits (PTA,13);

	}
	return u8_Status;
}





/********************************************************
**函数名：ECU_MC33771_PORT_INIT
**功能：	MC33771相关硬件模块初始化
**输入：	无
**输出：	无
**注意：	根据实际硬件电路确认通道
*********************************************************/
void ECU_MC33771_PORT_INIT(void)
{
	BSW_GPIO_MUX_CONFIG(Bsw_Port_E,15,PORT_MUX_ALT3);			/* 	PE15: 	MUX = ALT3, LPSPI2_SCK */
	BSW_GPIO_MUX_CONFIG(Bsw_Port_A,8,PORT_MUX_ALT3);			/* 	PA8: 	MUX = ALT3, LPSPI2_MISO */
	BSW_GPIO_MUX_CONFIG(Bsw_Port_E,16,PORT_MUX_ALT3);			/* 	PE16: 	MUX = ALT3, LPSPI2_MOSI */
	BSW_GPIO_MUX_CONFIG(Bsw_Port_A,9,PORT_MUX_ALT3);			/* 	PA9: 	MUX = ALT3, LPSPI2_PCS0 */
	BSW_GPIO_MUX_CONFIG(Bsw_Port_A,13,PORT_MUX_AS_GPIO);		/*	PA13:	MUX = ALT1, GPIO_PTA13 */
	BSW_GPIO_Direction(PTA,13,1);								/*  GPIO_PTE11设置为输出	MC33771_RESET */

	/********************LPSPI1配置**************************/
	BSW_LPSPI_INIT(MC33771_LPSPI1_Cfg);
	/*****************DMA通道对应的设置**********************/
	BSW_DMAMUX_INIT(SPI1_TxDma.DMA_Ch,EDMA_REQ_LPSPI2_TX);
	SPI1_TxDma.SrcAddr = G_MC33771_Tx_Addr;
	SPI1_TxDma.DestAddr = (u32)&(LPSPI2->TDR);
	BSW_DMA_INIT_CFG(SPI1_TxDma);

	BSW_DMAMUX_INIT(SPI1_RxDma.DMA_Ch,EDMA_REQ_LPSPI2_RX);
	SPI1_RxDma.SrcAddr = (u32)&(LPSPI2->RDR);
	SPI1_RxDma.DestAddr = G_MC33771_Rx_Addr;
	BSW_DMA_INIT_CFG(SPI1_RxDma);
}

/***************MC33771唤醒************/
void ECU_MC33771_WakeUp(void)
{
	/******************************************************
	BSW_GPIO_MUX_CONFIG(Bsw_Port_D,3,PORT_MUX_AS_GPIO);
	BSW_GPIO_Direction(PTD,3,1);
	MC33771_SPICSB(0);
	APPL_Delay_us(100);
	MC33771_SPICSB(1);
	BSW_GPIO_MUX_CONFIG(Bsw_Port_D,3,PORT_MUX_ALT3);
	APPL_Delay_us(300);
	******************************************************/
}


/*! \brief packs a 40bit message frame and returns a 5 byte buffer
 * @param pu8Buf     5 byte (40bit) long buffer
 * @param u16Data    16 bit data field to be packed
 * @param u8Addr     8 bit address field to be packed
 * @param u4CID      4 bit Cluster ID to be packed
 * @param u4Cmd      4 bit Command to be packed
 */
void ECU_MC33771_PackFrame(u8 *pu8Buf, u16 u16Data, u8 u8Addr, u8 u4CID, u8 u4Cmd)
{
	*(pu8Buf+0) = (u8) (u16Data >> 8);
	*(pu8Buf+1) = (u8) (u16Data);
	*(pu8Buf+2) = (u8) (u8Addr);
	*(pu8Buf+3) = (u8) ((u4CID&0xF)<<4) | (u4Cmd&0xF);
	/*DMA模式下需要把此数值存放在最后一个数值放在最开始位置*/
	*(pu8Buf+4) = MC33771_CRC8(pu8Buf, 4);
}

/*检验接收数据的结果CRC-8验证*/
inline u16 ECU_MC33771_CHECK_DATA(u8* u16_Data_Arr)
{
	u16 u16_Value = 0;
	if(MC33771_CRC8(u16_Data_Arr+1, 5) == 0)	/*CRC校验整帧数据 返回0x00*/
	{
		u16_Value =  (u16) ((u16_Data_Arr[1] << 8) | u16_Data_Arr[2]);
		Diag_InnerCommunicationFlt_Flg = 0;
	}
	else
	{
		Diag_InnerCommunicationFlt_Flg = 1;
	}
	return u16_Value;
}



/********启动MC33771的DMA传输*********/
void ECU_MC33771_DMA_START(void)
{
	BSW_DMA_REINIT(DMA_CH2,G_MC33771_Tx_Addr,(u32)(&(LPSPI2->TDR)),MSGLEN);	
	BSW_DMA_REINIT(DMA_CH3,(u32)(&(LPSPI2->RDR)),G_MC33771_Rx_Addr,MSGLEN+1);
	BSW_DMA_START(DMA_CH2);
	BSW_DMA_START(DMA_CH3);
}


/******* 返回当前LPSPI是否处于空闲***********/
inline bool ECU_MC33771_READY_STS(void)
{
	return G_b_DMA3_IDE_Flg;
}



void ECU_MC33771_INIT(void)
{
	G_u8_Arr_len = 13;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = (u32)MC33771_Init;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}



void ECU_MC33771_Normal(void)
{
	G_u8_Arr_len = 2;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = (u32)MC33771_NORMAL;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}

inline void ECU_MC33771_Clear_Flt(void)
{
	G_u8_Arr_len = 7;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = (u32)Mc33771_Clear;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}

inline void ECU_MC33771_GVal_SttCov(void)
{
	G_u8_Arr_len = 33;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = (u32)Mc33771_VCT;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}

void ECU_MC33771_Blance(u32 u32_Tx_Addr,u8 u8_Lenth)
{
	G_u8_Arr_len = u8_Lenth;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = u32_Tx_Addr;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}



void ECU_MC33771_CMD(u32 u32_Tx_Addr,u8 u8_Lenth)
{
	G_u8_Arr_len = u8_Lenth;
	G_b_DMA3_IDE_Flg = false;
	G_MC33771_Tx_Addr = u32_Tx_Addr;
	G_MC33771_Rx_Addr = (u32)G_MC3371_Rxbuff;
	ECU_MC33771_DMA_START();
}



/****************************中断处理函数*********************/
void ECU_MC33771_DMA3(void)
{
	static u8 s_u8_Dma3_Count = 0;
	
	if(s_u8_Dma3_Count < G_u8_Arr_len)
	{
		G_MC33771_Rx_Addr = G_MC33771_Rx_Addr + 6;
		G_MC33771_Tx_Addr = G_MC33771_Tx_Addr + 5;		/*传输的结构体长度为6个字节 地址每次需要偏移6*/
		BSW_DMA_REINIT(DMA_CH3,(u32)(&(LPSPI2->RDR)),G_MC33771_Rx_Addr,MSGLEN+1);
		BSW_DMA_REINIT(DMA_CH2,G_MC33771_Tx_Addr,(u32)(&(LPSPI2->TDR)),MSGLEN);			
		BSW_DMA_START(DMA_CH2);
		BSW_DMA_START(DMA_CH3);
		s_u8_Dma3_Count ++;
	}
	else
	{
		G_b_DMA3_IDE_Flg = true;
		s_u8_Dma3_Count = 0;
	}
}























/*************************************************
void ECU_MC33771_CCELL_VCT(u16* P_u16_Value)
{
	u8 u8_Count = 0;
	u8* P_u8_Data = (u8*)G_MC3371_Rxbuff;
	for(u8_Count = 0;u8_Count<G_u8_Arr_len;u8_Count++)
	{
		P_u16_Value[u8_Count] = ECU_MC33771_CHECK_DATA(P_u8_Data);
		P_u8_Data = P_u8_Data + 6;
	}
}
**********************************************/



void ECU_MC33771_CCELL_VCT(u16* P_u16_Value)
{
	u8 u8_Count = 0;
	u16 u16_Value = 0;
	u16 u16_OldData;

	u8* P_u8_Data = (u8*)G_MC3371_Rxbuff;
	for(u8_Count = 0;u8_Count<G_u8_Arr_len;u8_Count++)
	{
		u16_OldData = P_u16_Value[u8_Count];
		if(MC33771_CRC8(P_u8_Data+1, 5) == 0) /*如果设备ID和读写指令为0x00 为无效数据*/
		{
			if(P_u8_Data[4] != 0x00 && P_u8_Data[3] != 0x00)
			{
				u16_Value = P_u8_Data[1];
				P_u16_Value[u8_Count] =  (u16) ((u16_Value << 8) | P_u8_Data[2]);
			}
			else
			{
				G_u8_Data_Err_Count ++;
				P_u16_Value[u8_Count] = u16_OldData;
			}
		}
		else
		{
			G_u8_Crc_Err_Count ++;
			P_u16_Value[u8_Count] = u16_OldData;
		}
		P_u8_Data = P_u8_Data + 6;
	}
}

u8 G_u8_Mc33771_Err_Count = 0;
u8 G_u8_ERR_Count = 0;
u8 ECU_MC33771_ERR_Check(void)
{
	u8 u8_reInit = 0;

	if(G_u8_Data_Err_Count < G_u8_Arr_len && G_u8_Crc_Err_Count < G_u8_Arr_len)
	{
		G_u8_ERR_Count = 0;
		G_u8_Mc33771_Err_Count = 0;
	}
	else
	{
		if(G_u8_Crc_Err_Count >= G_u8_Arr_len)
		{
			G_u8_ERR_Count |= 0x80;
		}
		if(G_u8_Data_Err_Count >= G_u8_Arr_len)
		{
			G_u8_ERR_Count |= 0x40;
		}
		if((G_u8_ERR_Count & 0x3F) >= 8)
		{
			G_u8_Mc33771_Err_Count ++;
			G_u8_ERR_Count = 0;
			u8_reInit = 1;
		}
		else
		{
			G_u8_ERR_Count ++;
		}
	}

	if(G_u8_Mc33771_Err_Count > 3)
	{
		if(G_u8_ERR_Count & 0x80)
		{
			Diag_InnerCommunicationFlt_Flg |= 1;
		}
		if(G_u8_ERR_Count & 0x40)
		{
			Diag_BCC_Mismatch_Flg |= 1;
		}
		G_u8_Mc33771_Err_Count = 4;
	}
	else
	{
		Diag_BCC_Mismatch_Flg = 0;
		Diag_InnerCommunicationFlt_Flg = 0;
	}
	G_u8_Data_Err_Count = 0;
	G_u8_Crc_Err_Count = 0;
	return u8_reInit;
}











/********************************************************
**函数名：	ECU_MC33771_ClltCellVol
**功能：	计算MC33771采集的单体电压值
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位V
*********************************************************/
float ECU_MC33771_ClltCellVol(u16 u16_Cell_Ad)
{
	float u16_Vol = 0;
	if(u16_Cell_Ad & 0x8000)
	{
		u16_Vol = (float)(u16_Cell_Ad & 0x7FFF);
		u16_Vol = u16_Vol * 5/0x7FFF;
	}
	else
	{
		u16_Vol = 0.0;
	}
	return u16_Vol;
}

/********************************************************
**函数名：	ECU_MC33771_ClltCurr
**功能：	计算MC33771采集的电流值
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位A	    采样电阻100μΩ
*********************************************************/
float ECU_MC33771_ClltCurr(u16 u16_Cell_Ad1,u16 u16_Cell_Ad2)
{
	/* with V2RES = 0.6 μV/LSB, 100μΩ */
	float u16_Vol = 0;
	s32 s32_Curr_Value = 0;
	s32_Curr_Value = u16_Cell_Ad1&0x7FFF;
	s32_Curr_Value = (s32_Curr_Value << 4)|((u16_Cell_Ad2&0x000F)<<0);
	if(s32_Curr_Value & BIT(18))
	{
		s32_Curr_Value |= 0xFFF80000;
	}
	u16_Vol = (float)s32_Curr_Value;
	/*current = rawCurrent * V2RES / Rshunt;*/
	u16_Vol = (u16_Vol * 6/1000);
	return u16_Vol;
}


/********************************************************
**函数名：	ECU_MC33771_BlanceTemp
**功能：	计算MC33771采集的TEMP温度
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位℃
*********************************************************/
float ECU_MC33771_BlanceTemp(u16 u16_Cell_Ad)
{
	u8 u8_Count = 0;
	static float S_u16_BLtVal = 0;
	float u16_Val = 0;

	if(u16_Cell_Ad & 0x8000)
	{
		u16_Cell_Ad = u16_Cell_Ad & 0x7FFF;
		for(u8_Count = 0;u8_Count < 34;u8_Count++)
		{
			if(u16_Cell_Ad >= G_u16_Blan_Adc[u8_Count+1] && u16_Cell_Ad <= G_u16_Blan_Adc[u8_Count])
			{
				u16_Val = G_u16_Blan_Adc[u8_Count] - G_u16_Blan_Adc[u8_Count+1];
				u16_Val = (float)(u16_Cell_Ad - G_u16_Blan_Adc[u8_Count+1])*5/u16_Val;
				u16_Val = (float)G_s8_Blan_Ntc[u8_Count + 1]  - u16_Val;
				break;
			}
		}
	}
	else
	{
		u16_Val = S_u16_BLtVal;
	}
	S_u16_BLtVal = u16_Val;
	return u16_Val;
}


/********************************************************
**函数名：	ECU_MC33771_ClltTemp
**功能：	计算MC33771采集的TEMP温度
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位℃
*********************************************************/
float ECU_MC33771_ClltTemp(u16 u16_Cell_Ad)
{
	u8 u8_Count = 0;
	static float S_u16_CtVal = 0;
	float u16_Val = 0;

	if(u16_Cell_Ad & 0x8000)
	{
		u16_Cell_Ad = u16_Cell_Ad & 0x7FFF;
		if(u16_Cell_Ad <= MC_NTC_Table[165])
		{
			u16_Val = 125;
		}
		else if(u16_Cell_Ad >= MC_NTC_Table[0])
		{
			u16_Val = -40;
		}
		else
		{
			Diag_TempSamplingShortGND_Flg = 0;
			Diag_TempSamplingShortPWR_Flg = 0;
			for(u8_Count = 0;u8_Count < 166;u8_Count++)
			{
				if(u16_Cell_Ad >= MC_NTC_Table[u8_Count+1] && u16_Cell_Ad <= MC_NTC_Table[u8_Count])
				{
					u16_Val = MC_NTC_Table[u8_Count] - MC_NTC_Table[u8_Count+1];
					u16_Val = (float)(u16_Cell_Ad - MC_NTC_Table[u8_Count+1])/u16_Val;
					u16_Val = (float)NTC_TEMP_Table[u8_Count + 1]  - u16_Val;
					break;
				}
			}
		}

		if(u16_Cell_Ad <= Short_GND_AD)
		{
			/* 短路到GND*/
			Diag_TempSamplingShortGND_Flg = 1;

		}
		else if(u16_Cell_Ad >= Short_POWR_AD)
		{
			/*开路 短路到VCC*/
			Diag_TempSamplingShortPWR_Flg = 1;
		}
	}
	else
	{
		u16_Val = S_u16_CtVal;
	}
	S_u16_CtVal = u16_Val;


	return u16_Val;
}
/********************************************************
**函数名：	ECU_MC33771_ClltPackVol
**功能：	计算MC33771采集的PACK包总电压值
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位V
*********************************************************/
float ECU_MC33771_ClltPackVol(u16 u16_Cell_Ad)
{
	float u16_Vol = 0;
	if(u16_Cell_Ad & 0x8000)
	{
		u16_Vol = (float)(u16_Cell_Ad & 0x7FFF);
		u16_Vol = u16_Vol * 80/0x7FFF;
	}
	else
	{
		u16_Vol = 0.0;
	}
	return u16_Vol;
}

/********************************************************
**函数名：	ECU_MC33771_ClltPackVol
**功能：	计算MC33771采集的PACK包总电压值
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位V
*********************************************************/
float ECU_MC33771_ClltFuseVol(u16 u16_Cell_Ad)
{
	float u16_Vol = 0.0;
	if(u16_Cell_Ad & 0x8000)
	{
		u16_Vol = (float)(u16_Cell_Ad & 0x7FFF);
		u16_Vol = 15.6864 + (u16_Vol - 675)*0.0064;
	}
	else
	{
		u16_Vol = 0.0;
	}
	return u16_Vol;
}

/********************************************************
**函数名：	ECU_MC33771_ClltRelayVol
**功能：	计算MC33771采集的继电器电压值
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位V
*********************************************************/
float ECU_MC33771_ClltRelayVol(u16 u16_Cell_Ad)
{
	float u16_Vol = 0.0;
	if(u16_Cell_Ad & 0x8000)
	{
		u16_Vol = (float)(u16_Cell_Ad & 0x7FFF);
		u16_Vol = u16_Vol * 65.45/ 0x7FFF;
	}
	else
	{
		u16_Vol = 0.0;
	}
	return u16_Vol;
}

/********************************************************
**函数名：	ECU_MC33771_IC_Temp
**功能：	计算MC33771采集的IC温度
**输入：	MC33711采集的AD值
**输出：	浮点型电压值
**注意：	单位℃
*********************************************************/
float ECU_MC33771_IC_Temp(u16 u16_Cell_Ad)
{
	float u16_Vol = 0.0;
	if(u16_Cell_Ad & 0x8000)
	{
		u16_Vol = (float)(u16_Cell_Ad & 0x7FFF);
		u16_Vol = (u16_Vol * 4/125) - 273.15;
	}
	else
	{
		u16_Vol = 0.0;
	}
	return u16_Vol;
}




#if Debug_MC33771

const MC33771_CMD_FLG MC33771_Init_Arr[16];
{
	{0x00,INIT,0x00,CmdRdLocal,0x74},
	{0x00,INIT,0x00,CmdRdLocal,0x74},				/*CheckSlave*/
	{0x00,INIT,0x01,CmdWrLocal,0x0B},				/*AssignCID*/
	{0x01,SYS_CFG1,0x0280,CmdWrLocal,0xDE},			/*启动33771转换使能	开启均衡总控制位*/
	{0x01,FAULT1_STATUS,0x0000,CmdWrLocal,0xDD},		/*复位 FAULT1_STATUS*/
	{0x01,FAULT2_STATUS,0x0000,CmdWrLocal,0x34},		/*复位 FAULT2_STATUS*/
	{0x01,FAULT3_STATUS,0x0000,CmdWrLocal,0x20},		/*复位 FAULT3_STATUS*/
	{0x01,FAULT_MASK1,0xFFFC,CmdWrLocal,0x5F},
/*{0x01,FAULT_MASK2,0x0000,CmdWrLocal},		*/
	{0x01,FAULT_MASK3,0x8000,CmdWrLocal,0xA5},
	{0x00,0x00,0x0000,0x00,0xB2},					/*提供时钟读取最后一个配置项的返回值*/
};



/********电流电压温度地址数组*********/
const u8 C_u8_MC33771_VCT_ARR[30]=
{
	/*首位字节丢弃 数值为0x0000*/
	MEAS_CELL1,
	MEAS_CELL2,
	MEAS_CELL3,
	MEAS_CELL4,
	/*MEAS_CELL5,*//*   5节单体短路 输出0xFFFF*/
	MEAS_CELL6,
	MEAS_CELL7,
	MEAS_CELL8,
	MEAS_CELL9,
	MEAS_CELL10,
	MEAS_CELL11,
	MEAS_CELL12,
	MEAS_CELL13,
	MEAS_CELL14,
	MEAS_AN0,						/*VOLT_B 	继电器外总电压+				14*/
	MEAS_AN1,						/*VOLT_C 	保险丝Fuse-Relay总压+		15*/
	MEAS_AN2,						/*NTC3_AD	BalancTemp				16*/
	MEAS_AN3,						/*NTC2_AD	PackTempNr2				17*/
	MEAS_AN4,						/*NTC1_AD	PackTempNr1				18*/
	MEAS_AN5,						/*FAE_ISENSE+  						19*/
	MEAS_AN6,						/*FAE_ISENSE-  						20*/
	MEAS_ISENSE1,				/*ISENSE+  							21*/
	MEAS_ISENSE2,				/*ISENSE-  							22*/
	MEAS_STACK,					/*STACK_VOL							23*/
	MEAS_IC_TEMP,				/*IC_TEMP								24*/
	CC_NB_SAMPLES,			/*电量消耗库伦量*/
	0x00,
	0x00,
};

/*******MC33771状态地址数组******/
const u8 C_u8_MC33771_VCT_STS[30]=
{
	/*首位字节丢弃 数值为0x0000*/
	00,
	CB1_CFG,
	CB2_CFG,
	CB3_CFG,
	CB4_CFG,
	/*CB5_CFG,*//*   5节单体短路 */
	CB6_CFG,
	CB7_CFG,
	CB8_CFG,
	CB9_CFG,
	CB10_CFG,
	CB11_CFG,
	CB12_CFG,
	CB13_CFG,
	CB14_CFG,
	CB_OPEN_FLT,					/*开路故障		14*/
	CB_SHORT_FLT,					/*短路故障		15*/
	CB_DRV_STS,						/*均衡驱动开关状态	16*/
	AN_OT_UT_FLT,					/*过温故障		17*/
	COM_STATUS,						/*通信CRC错误次数	18*/
	FAULT1_STATUS,					/*Fault状态寄存器1  					19*/
	FAULT2_STATUS,					/*Fault状态寄存器2 					20*/
	FAULT3_STATUS,					/*Fault状态寄存器3 					21*/
	WAKEUP_MASK1,					/*唤醒事件寄存器1 						22*/
	WAKEUP_MASK2,					/*唤醒事件寄存器2 						23*/
	WAKEUP_MASK3,					/*唤醒事件寄存器3 						24*/
	SILICON_REV,					/*silicon revision					25*/
	0x00,
	0x00,
};


#endif




































































































































